`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    14:03:29 10/12/2011 
// Design Name: 
// Module Name:    up_core 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module up_stream_core #(
  parameter SIMULATION                  = "FALSE", // Indicates whether SIM or HW
  parameter LANES                       = 4        // Number of PCIe Lanes
)(
  input pcie_clk,                                              // PCIe System Clock - P
  input pcie_rst,                                              // PCIe System Reset

  output [LANES-1:0] pcie_txn,
  output [LANES-1:0] pcie_txp,
  input  [LANES-1:0] pcie_rxn,
  input  [LANES-1:0] pcie_rxp,

  input               clk,
  input               rst,
  
  input               tx_tvalid,
  output              tx_tready,
  input   [127:0]     tx_tdata,
  input   [3:0]       tx_tstrb,
  input               tx_tlast,
      
  output              rx_tvalid,
  input               rx_tready,
  output  [127:0]     rx_tdata,
  output  [3:0]       rx_tstrb,
  output              rx_tlast,

  input   [31:0]  S_AWADDR,
  input           S_AWVALID,
  output          S_AWREADY,
  input   [31:0]  S_WDATA,
  input   [3:0]   S_WSTRB,
  input           S_WVALID,
  output          S_WREADY,
  output  [1:0]   S_BRESP,
  output          S_BVALID,
  input           S_BREADY,
  input   [31:0]  S_ARADDR,
  input           S_ARVALID,
  output          S_ARREADY,
  output  [31:0]  S_RDATA,
  output  [1:0]   S_RRESP,
  output          S_RVALID,
  input           S_RREADY,

  output  [31:0]      cfg_do,
  input   [31:0]      cfg_di,
  input   [3:0]       cfg_byte_en,
  output              cfg_rd_wr_done,
  input   [9:0]       cfg_dwaddr,
  input               cfg_rd_en,
  input               cfg_wr_en,
  
  output              link_up  
);


  assign S_AWREADY = 1'b0;
  assign S_WREADY = 1'b0;
  assign S_BRESP = 2'b0;
  assign S_BVALID = 1'b0;
  assign S_ARREADY = 1'b0;
  assign S_RDATA = 32'b0;
  assign S_RRESP = 2'b0;
  assign S_RVALID = 1'b0;
  
  wire [3:0]  tx_tuser = 4'b0; //{t_src_dsc, tx_str,  tx_err_fwd, tx_ecrc_gen}

  wire        rx128_tvalid;
  wire        rx128_tready;
  wire [127:0] rx128_tdata;
  wire [3:0]  rx128_tstrb;
  wire        rx128_tlast;
  
  wire        tx128_tvalid;
  wire        tx128_tready;
  wire [127:0] tx128_tdata;
  wire [3:0]  tx128_tstrb;
  wire        tx128_tlast;

  wire        rx64_tvalid;
  wire        rx64_tready;
  wire [63:0] rx64_tdata;
  wire [7:0]  rx64_tkeep;
  wire        rx64_tlast;
  
  wire        tx64_tvalid;
  wire        tx64_tready;
  wire [63:0] tx64_tdata;
  wire [7:0]  tx64_tkeep;
  wire        tx64_tlast;
  
  wire [1:0]  rx64_tstrb = {rx64_tkeep[4], rx64_tkeep[0]};
  wire [1:0]  tx64_tstrb;
  assign tx64_tkeep = {{4{tx64_tstrb[1]}}, {4{tx64_tstrb[0]}}};
  
  wire user_clk;
  wire user_rst;
  wire fifo_rst = user_rst || rst;
  
  axis_async_fifo128
  rx_fifo(
    .rst      (fifo_rst),
  
    .s_clk    (user_clk),
    .s_tvalid (rx128_tvalid),
    .s_tready (rx128_tready),
    .s_tdata  (rx128_tdata),
    .s_tstrb  (rx128_tstrb),
    .s_tlast  (rx128_tlast),

    .m_clk    (clk),
    .m_tvalid (rx_tvalid),
    .m_tready (rx_tready),
    .m_tdata  (rx_tdata),
    .m_tstrb  (rx_tstrb),
    .m_tlast  (rx_tlast));

  axis_async_fifo128
  tx_fifo(
    .rst      (fifo_rst),
    
    .s_clk    (clk),
    .s_tvalid (tx_tvalid),
    .s_tready (tx_tready),
    .s_tdata  (tx_tdata),
    .s_tstrb  (tx_tstrb),
    .s_tlast  (tx_tlast),
    
    .m_clk    (user_clk),
    .m_tvalid (tx128_tvalid),
    .m_tready (tx128_tready),
    .m_tdata  (tx128_tdata),
    .m_tstrb  (tx128_tstrb),
    .m_tlast  (tx128_tlast));
  
  axis_double_width #(
    .DWIDTH     (64),
    .KWIDTH     (2))
  rx_width_conv (
    .clk        (user_clk),
    .rst        (user_rst),
    
    .s_tvalid  (rx64_tvalid),
    .s_tready  (rx64_tready),
    .s_tdata   (rx64_tdata),
    .s_tkeep   (rx64_tstrb),
    .s_tlast   (rx64_tlast),
  
    .m_tvalid  (rx128_tvalid),
    .m_tready  (rx128_tready),
    .m_tdata   (rx128_tdata),
    .m_tkeep   (rx128_tstrb),
    .m_tlast   (rx128_tlast));
  
  axis_half_width #(
    .DWIDTH     (128),
    .KWIDTH     (4))
  tx_width_conv (
    .clk        (user_clk),
    .rst        (user_rst),
    
    .s_tvalid  (tx128_tvalid),
    .s_tready  (tx128_tready),
    .s_tdata   (tx128_tdata),
    .s_tkeep   (tx128_tstrb),
    .s_tlast   (tx128_tlast),
  
    .m_tvalid  (tx64_tvalid),
    .m_tready  (tx64_tready),
    .m_tdata   (tx64_tdata),
    .m_tkeep   (tx64_tstrb),
    .m_tlast   (tx64_tlast));

`ifdef V7

  pcie_7x_v1_2 #(
    .PL_FAST_TRAIN                  (SIMULATION),
    .LINK_CAP_MAX_LINK_WIDTH        (LANES),
    .HEADER_TYPE                    (8'h1),
    .IS_SWITCH                      ("TRUE"),
    .PCIE_CAP_DEVICE_PORT_TYPE      (4'b0101),
    .UPSTREAM_FACING                ("TRUE"),
    .DISABLE_BAR_FILTERING          ("TRUE"),
    .ENABLE_RX_TD_ECRC_TRIM         ("TRUE"),
    .BAR0                           (32'h00000000),
    .BAR1                           (32'h00000000),
    .BAR2                           (32'h00FFFFFF),
    .BAR3                           (32'hFFFFFFFF),
    .BAR4                           (32'hFFFFFFFF),
    .BAR5                           (32'hFFFFFFFF)
    )
  pcie(
    .pci_exp_txn                    (pcie_txn),
    .pci_exp_txp                    (pcie_txp),
    .pci_exp_rxn                    (pcie_rxn),
    .pci_exp_rxp                    (pcie_rxp),

    .user_clk_out                   (user_clk),
    .user_reset_out                 (user_rst),
    .user_lnk_up                    (link_up),
              
    .tx_buf_av                      (),
    .tx_err_drop                    (),
    .tx_cfg_req                     (),
    .s_axis_tx_tready               (tx64_tready),
    .s_axis_tx_tdata                (tx64_tdata),
    .s_axis_tx_tkeep                (tx64_tkeep),
    .s_axis_tx_tuser                (tx_tuser),
    .s_axis_tx_tlast                (tx64_tlast),
    .s_axis_tx_tvalid               (tx64_tvalid),
    .tx_cfg_gnt                     (1'b1),
              
    .m_axis_rx_tdata                (rx64_tdata),
    .m_axis_rx_tkeep                (rx64_tkeep),
    .m_axis_rx_tlast                (rx64_tlast),
    .m_axis_rx_tvalid               (rx64_tvalid),
    .m_axis_rx_tready               (rx64_tready),
    .m_axis_rx_tuser                (),
    .rx_np_ok                       (1'b1),
    .rx_np_req                      (1'b1),
              
    .fc_cpld                        (),
    .fc_cplh                        (),
    .fc_npd                         (),
    .fc_nph                         (),
    .fc_pd                          (),
    .fc_ph                          (),
    .fc_sel                         (3'b100),
              
    .cfg_status                     (),
    .cfg_command                    (),
    .cfg_dstatus                    (),
    .cfg_dcommand                   (),
    .cfg_lstatus                    (),
    .cfg_lcommand                   (),
    .cfg_dcommand2                  (),
    .cfg_pcie_link_state            (),

    .cfg_pmcsr_pme_en               (),
    .cfg_pmcsr_powerstate           (),
    .cfg_pmcsr_pme_status           (),
    .cfg_received_func_lvl_rst      (),

    .cfg_mgmt_di                    (32'b0),
    .cfg_mgmt_byte_en               (4'b0),
    .cfg_mgmt_dwaddr                (cfg_dwaddr),
    .cfg_mgmt_wr_en                 (1'b0),
    .cfg_mgmt_rd_en                 (cfg_rd_en),
    .cfg_mgmt_wr_readonly           (1'b0),
    .cfg_mgmt_do                    (cfg_do),
    .cfg_mgmt_rd_wr_done            (cfg_rd_wr_done),

    .cfg_err_ecrc                   (1'b0),
    .cfg_err_ur                     (1'b0),
    .cfg_err_cpl_timeout            (1'b0),
    .cfg_err_cpl_unexpect           (1'b0),
    .cfg_err_cpl_abort              (1'b0),
    .cfg_err_posted                 (1'b0),
    .cfg_err_cor                    (1'b0),
    .cfg_err_atomic_egress_blocked  (1'b0),
    .cfg_err_internal_cor           (1'b0),
    .cfg_err_malformed              (1'b0),
    .cfg_err_mc_blocked             (1'b0),
    .cfg_err_poisoned               (1'b0),
    .cfg_err_norecovery             (1'b0),
    .cfg_err_tlp_cpl_header         (48'b0),
    .cfg_err_cpl_rdy                (),
    .cfg_err_locked                 (1'b0),
    .cfg_err_acs                    (1'b0),
    .cfg_err_internal_uncor         (1'b0),

    .cfg_trn_pending                (1'b0),
    .cfg_pm_halt_aspm_l0s           (1'b0),
    .cfg_pm_halt_aspm_l1            (1'b0),
    .cfg_pm_force_state_en          (1'b0),
    .cfg_pm_force_state             (2'b0),

    .cfg_dsn                        (64'b0),

    .cfg_interrupt                  (1'b0),
    .cfg_interrupt_rdy              (),
    .cfg_interrupt_assert           (1'b0),
    .cfg_interrupt_di               (8'b0),
    .cfg_interrupt_do               (),
    .cfg_interrupt_mmenable         (),
    .cfg_interrupt_msienable        (),
    .cfg_interrupt_msixenable       (),
    .cfg_interrupt_msixfm           (),
    .cfg_interrupt_stat             (1'b0),
    .cfg_pciecap_interrupt_msgnum   (5'b0),

    .cfg_to_turnoff                 (),
    .cfg_turnoff_ok                 (1'b0),
    .cfg_bus_number                 (),
    .cfg_device_number              (),
    .cfg_function_number            (),
    .cfg_pm_wake                    (1'b0),
    
    .cfg_pm_send_pme_to             (1'b0),
    .cfg_ds_bus_number              (8'b0),
    .cfg_ds_device_number           (5'b0),
    .cfg_ds_function_number         (3'b0),

    .cfg_mgmt_wr_rw1c_as_rw         (1'b0),
    .cfg_msg_received               (),
    .cfg_msg_data                   (),

    .cfg_bridge_serr_en             (),
    .cfg_slot_control_electromech_il_ctl_pulse(),
    .cfg_root_control_syserr_corr_err_en(),
    .cfg_root_control_syserr_non_fatal_err_en(),
    .cfg_root_control_syserr_fatal_err_en(),
    .cfg_root_control_pme_int_en    (),
    .cfg_aer_rooterr_corr_err_reporting_en(),
    .cfg_aer_rooterr_non_fatal_err_reporting_en(),
    .cfg_aer_rooterr_fatal_err_reporting_en(),
    .cfg_aer_rooterr_corr_err_received(),
    .cfg_aer_rooterr_non_fatal_err_received(),
    .cfg_aer_rooterr_fatal_err_received(),

    .cfg_msg_received_err_cor       (),
    .cfg_msg_received_err_non_fatal (),
    .cfg_msg_received_err_fatal     (),
    .cfg_msg_received_pme_to_ack    (),
    
    .pl_directed_link_change        (2'b0),
    .pl_directed_link_width         (2'b0),
    .pl_directed_link_speed         (1'b0),
    .pl_directed_link_auton         (1'b0),
    .pl_upstream_prefer_deemph      (1'b0),

    .pl_sel_lnk_rate                (),
    .pl_sel_lnk_width               (),
    .pl_ltssm_state                 (),
    .pl_lane_reversal_mode          (),

    .pl_phy_lnk_up                  (),
    .pl_tx_pm_state                 (),
    .pl_rx_pm_state                 (),

    .pl_link_upcfg_cap              (),
    .pl_link_gen2_cap               (),
    .pl_link_partner_gen2_supported (),
    .pl_initial_link_width          (),

    .pl_directed_change_done        (),

    .pl_received_hot_rst            (),
    
    .pl_transmit_hot_rst            (1'b0),
    .pl_downstream_deemph_source    (1'b0),

    .cfg_err_aer_headerlog          (128'b0),
    .cfg_aer_interrupt_msgnum       (5'b0),
    .cfg_err_aer_headerlog_set      (),
    .cfg_aer_ecrc_check_en          (),
    .cfg_aer_ecrc_gen_en            (),

    .cfg_vc_tcvc_map                (),

    .sys_clk                        (pcie_clk),
    .sys_reset                      (pcie_rst)
    );
    
`else

  v6_pcie_v2_5 #(
    .PL_FAST_TRAIN                  (SIMULATION),
    .LINK_CAP_MAX_LINK_WIDTH        (LANES)
//    .HEADER_TYPE                    (8'h1),
//    .IS_SWITCH                      ("TRUE"),
//    .PCIE_CAP_DEVICE_PORT_TYPE      (4'b0101),
//    .UPSTREAM_FACING                ("TRUE"),
//    .DISABLE_BAR_FILTERING          ("TRUE"),
//    .ENABLE_RX_TD_ECRC_TRIM         ("TRUE"),
//    .BAR0                           (32'h00000000),
//    .BAR1                           (32'h00000000),
//    .BAR2                           (32'h00FFFFFF),
//    .BAR3                           (32'hFFFFFFFF),
//    .BAR4                           (32'hFFFFFFFF),
//    .BAR5                           (32'hFFFFFFFF)
    )
  pcie(
    .pci_exp_txn                    (pcie_txn),
    .pci_exp_txp                    (pcie_txp),
    .pci_exp_rxn                    (pcie_rxn),
    .pci_exp_rxp                    (pcie_rxp),

    .user_clk_out                   (user_clk),
    .user_reset_out                 (user_rst),
    .user_lnk_up                    (link_up),
              
    .tx_buf_av                      (),
    .tx_err_drop                    (),
    .tx_cfg_req                     (),
    .s_axis_tx_tready               (tx64_tready),
    .s_axis_tx_tdata                (tx64_tdata),
    .s_axis_tx_tkeep                (tx64_tkeep),
    .s_axis_tx_tuser                (tx_tuser),
    .s_axis_tx_tlast                (tx64_tlast),
    .s_axis_tx_tvalid               (tx64_tvalid),
    .tx_cfg_gnt                     (1'b1),
              
    .m_axis_rx_tdata                (rx64_tdata),
    .m_axis_rx_tkeep                (rx64_tkeep),
    .m_axis_rx_tlast                (rx64_tlast),
    .m_axis_rx_tvalid               (rx64_tvalid),
    .m_axis_rx_tready               (rx64_tready),
    .m_axis_rx_tuser                (),
    .rx_np_ok                       (1'b1),
              
    .fc_cpld                        (),
    .fc_cplh                        (),
    .fc_npd                         (),
    .fc_nph                         (),
    .fc_pd                          (),
    .fc_ph                          (),
    .fc_sel                         (3'b100),
              
    .cfg_status                     (),
    .cfg_command                    (),
    .cfg_dstatus                    (),
    .cfg_dcommand                   (),
    .cfg_lstatus                    (),
    .cfg_lcommand                   (),
    .cfg_dcommand2                  (),
    .cfg_pcie_link_state            (),

    .cfg_pmcsr_pme_en               (),
    .cfg_pmcsr_powerstate           (),
    .cfg_pmcsr_pme_status           (),

    .cfg_di                         (32'b0),
    .cfg_byte_en                    (4'b0),
    .cfg_dwaddr                     (cfg_dwaddr),
    .cfg_wr_en                      (1'b0),
    .cfg_rd_en                      (cfg_rd_en),
    .cfg_do                         (cfg_do),
    .cfg_rd_wr_done                 (cfg_rd_wr_done),

    .cfg_err_ecrc                   (1'b0),
    .cfg_err_ur                     (1'b0),
    .cfg_err_cpl_timeout            (1'b0),
    .cfg_err_cpl_unexpect           (1'b0),
    .cfg_err_cpl_abort              (1'b0),
    .cfg_err_posted                 (1'b0),
    .cfg_err_cor                    (1'b0),
    .cfg_err_tlp_cpl_header         (48'b0),
    .cfg_err_cpl_rdy                (),
    .cfg_err_locked                 (1'b0),

    .cfg_trn_pending                (1'b0),

    .cfg_dsn                        (64'b0),

    .cfg_interrupt                  (1'b0),
    .cfg_interrupt_rdy              (),
    .cfg_interrupt_assert           (1'b0),
    .cfg_interrupt_di               (8'b0),
    .cfg_interrupt_do               (),
    .cfg_interrupt_mmenable         (),
    .cfg_interrupt_msienable        (),
    .cfg_interrupt_msixenable       (),
    .cfg_interrupt_msixfm           (),

    .cfg_to_turnoff                 (),
    .cfg_turnoff_ok                 (1'b0),
    .cfg_bus_number                 (),
    .cfg_device_number              (),
    .cfg_function_number            (),
    .cfg_pm_wake                    (1'b0),
        
    .pl_directed_link_change        (2'b0),
    .pl_directed_link_width         (2'b0),
    .pl_directed_link_speed         (1'b0),
    .pl_directed_link_auton         (1'b0),
    .pl_upstream_prefer_deemph      (1'b0),
    .pl_sel_link_rate               (),
    .pl_sel_link_width              (),
    .pl_ltssm_state                 (),
    .pl_lane_reversal_mode          (),
    .pl_link_upcfg_capable          (),
    .pl_link_gen2_capable           (),
    .pl_link_partner_gen2_supported (),
    .pl_initial_link_width          (),
    .pl_received_hot_rst            (),
    
    .sys_clk                        (pcie_clk),
    .sys_reset                      (pcie_rst)
    );

`endif

endmodule
